package com.fuchuang.seckillsystem.provider;

import com.fuchuang.seckillsystem.entity.MyUserDetails;
import com.fuchuang.seckillsystem.entity.PreliminarySelect;
import com.fuchuang.seckillsystem.service.IPreliminarySelectService;
import com.fuchuang.seckillsystem.service.impl.UserDetailServiceImpl;
import com.fuchuang.seckillsystem.utils.Sm4Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 自定义登录处理逻辑
 */
@Component
public class LoginAuthProvider implements AuthenticationProvider {
    
    @Autowired
    private UserDetailServiceImpl userDetailService;
    
    @Autowired
    private IPreliminarySelectService preliminarySelectService;
    
    @Autowired
    private Sm4Utils sm4Utils;
    
    @Override
    public Authentication authenticate(Authentication auth) throws AuthenticationException {
        //获取用户名和密码
        String username = auth.getName();
        String password = (String) auth.getCredentials();
        //从缓存中拿登录对象
        UserDetails userDetail = userDetailService.loadUserByUsername(username);
        if (!userDetail.isEnabled()) {
            throw new DisabledException("该账号已禁用，请联系管理员");
        } else if (!userDetail.isAccountNonExpired()) {
            throw new AccountExpiredException("该账号已过期,请联系管理员");
        } else if (!userDetail.isAccountNonLocked()) {
            throw new LockedException("该账号已被锁定，请联系管理员");
        } else if (!userDetail.isCredentialsNonExpired()) {
            throw new CredentialsExpiredException("该账号的登录凭证已过期，请重新登录");
        }
        if (!sm4Utils.match(password, userDetail.getPassword())) {
            throw new BadCredentialsException("密码错误请重新输入");
        }
        MyUserDetails myUserDetails = (MyUserDetails) userDetail;
        //添加初筛记录
        preliminarySelectService.addPreliminarySelect(addPreliminarySelectParams(myUserDetails));
        return new UsernamePasswordAuthenticationToken(userDetail, password, userDetail.getAuthorities());
    }
    
    // supports函数用来指明该Provider是否适用于该类型的认证，如果不合适，则寻找另一个Provider进行验证处理。
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
    
    private PreliminarySelect addPreliminarySelectParams(MyUserDetails userDetails) {
        PreliminarySelect preliminarySelect = new PreliminarySelect();
        preliminarySelect.setIsPass(userDetails.getStatus());
        preliminarySelect.setIsValid(1);
        preliminarySelect.setUserId(userDetails.getId());
        Date date = new Date();
        preliminarySelect.setCreateTime(date);
        preliminarySelect.setUpdateTime(date);
        return preliminarySelect;
    }
}
